function getParameterNames(fn) {
	if (typeof fn !== "function") return [];
	var COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;
	var code = fn.toString().replace(COMMENTS, "");
	var result = code
		.slice(code.indexOf("(") + 1, code.indexOf(")"))
		.match(/([^\s,]+)/g);
	return result === null ? [] : result;
}

function codeFormat(value) {
	var moduleExports = eval(
		"var module = {};var require=function(){}\n" + value
	);


	if (typeof moduleExports == "function") {
		let parameter = getParameterNames(moduleExports);
		let parameterStr = parameter.length ? "," + parameter.join(",") : "";
		return `
var path = require('path');
var _srcplugin = path.join(path.resolve(), '/pluginsInfo.js');
var pluginsInfo = require(_srcplugin);

var tryCatch = function(action){
	try{
		action();
	} catch (e){
		//TODO handle the exception
	}
}

module.exports = async function(callback, system ${parameterStr}) {

	if(!system) {
		system = {};
	}

	for (var ______key in pluginsInfo) {
		system[______key] = pluginsInfo[______key]
	}

	system.isWriteState = false;
	if (!system.channel) {
		system.channel = {};
	}

	if (system.channel.parameter) {
		tryCatch(function(){
			system.channel.parameter = JSON.parse(system.channel.parameter);
		});
	}

	if (!system.sesstion) {
		system.sesstion = {};
	} else {
		tryCatch(function(){
			system.sesstion = JSON.parse(system.sesstion);
		});
	}
	
	if(!system.debugs) {
		system.debugs = [];
	}
	
	if(!system.notifys) {
		system.notifys = [];
	}

	system.ClearChannel = function() {
		system.sesstion = null;
		system.channel.key = null;
		system.channel.parameter = null;
	};

	system.Notify = function(channel, message) {
		system.notifys.push({
			channel: channel.toString(),
			message: message.toString()
		});
	};

	var console = {
		log:function() {
			if (system.isdebug){
				if (arguments.length) {
					system.debugs.push(arguments.length == 1 ? arguments[0] : arguments);
				}
			}
		}
	};

	${value.replace(/module.exports/g, 'var module_exports_action')}
	module_exports_action = module_exports_action.bind(system);
	try{
		system.result = await module_exports_action(${parameter.join(",")});
	} catch(ex) {
		callback(ex, null); 
	}

	if (system.notifys.length) {
		system.notifys = JSON.stringify(system.notifys);
	} else {
		system.notifys = "";
	}

	callback(null, system);
}`;
	}

	else if (typeof moduleExports == "object") {
		var functionstr = [];
		var headerContent = value.split("module.exports")[0];
		for (const key in moduleExports) {
			let keyName = key.toLowerCase();
			const moduleObject = moduleExports[key];

			var fnString = moduleObject.toString();
			if (fnString.length > key.length) {
				if (fnString.substr(0, key.length) == key) {
					fnString = fnString.replace(key,"function");
				}
			}

			if (typeof moduleObject == "function") {
				let parameter = getParameterNames(moduleObject);
				let parameterStr = parameter.length
					? "," + parameter.join(",")
					: "";
				functionstr.push(`${keyName}: async function(callback, system ${parameterStr}) {

	if(!system) {
		system = {};
	}
	system.isWriteState = false;
	if (!system.channel) {
		system.channel = {};
	}

	if (system.channel.parameter) {
		tryCatch(function(){
			system.channel.parameter = JSON.parse(system.channel.parameter);
		});
	}

	for (var ______key in pluginsInfo) {
		system[______key] = pluginsInfo[______key]
	}

	if (!system.sesstion) {
		system.sesstion = {};
	} else {
		tryCatch(function(){
			system.sesstion = JSON.parse(system.sesstion);
		});
	}
	
	if(!system.debugs) {
		system.debugs = [];
	}
	
	if(!system.notifys) {
		system.notifys = [];
	}

	system.Notify = function(channel, message) {
		system.notifys.push({
		channel: channel.toString(),
		message: message.toString()
		});
	};

	var console = {
		log:function() {
			if (system.isdebug){
				if (arguments.length) {
					system.debugs.push(arguments.length == 1 ? arguments[0] : arguments);
				}
			}
		}
	};

	var module_exports_action = ${fnString}.bind(system);
	try{
		system.result = await module_exports_action(${parameter.join(",")});
	} catch(ex) {
		callback(ex, null); 
	}

	if (system.notifys.length) {
		system.notifys = JSON.stringify(system.notifys);
	} else {
		system.notifys = "";
	}

	callback(null, system);
}`);
			}

			else {
				functionstr.push(`${key}:${moduleObject}`);
			}
		}
		return `
${headerContent} 

var path = require('path');
var _srcplugin = path.join(path.resolve(), '/pluginsInfo.js');
var pluginsInfo = require(_srcplugin);

var tryCatch = function(action){
	try{
		action();
	} catch (e){
		//TODO handle the exception
	}
}
module.exports = { ${functionstr.join(
			","
		)} }`;
	}
}

module.exports = function (callback, code) {
	callback(null, codeFormat(code));
}